﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Collections;

//using MathNet.Numerics;

using System.Numerics;

namespace Xuhengxiao.Math
{
    /// <summary>
    /// 算术表达式类
    /// </summary>
    public   class ArithmeticExpression
    {
        private static  bool _isReal=true;//默认只是实数
        
        /// <summary>
        /// 是否是实数,这个支持实数运算和虚数运算
        /// </summary>
        public static  bool isReal
        {
            get { return _isReal; }
            set { _isReal = value; }
        }

        private  enumJiaoDuDanWei _JiaoDuDanWei = enumJiaoDuDanWei.JiaoDu;
        /// <summary>
        /// 角度单位
        /// </summary>
        public   enumJiaoDuDanWei  JiaoDuDanWei
        {
            get { return _JiaoDuDanWei; }
            set { _JiaoDuDanWei = value; }
        }
        

        
        
        /// <summary>
        /// 这个是支持运算的数组
        /// </summary>
        private static ClsPhrase[] arrClsPhrase;

        /// <summary>
        /// 这个保存的是数存储变量和常数,这个是共享的
        /// </summary>
        private static ClsPhrase[] arrClsPhrase2= new ClsPhrase[] {
                new ClsPhrase (enumPhraseType.number,"AX",7,0,new Complex(0,0),null),
                new ClsPhrase (enumPhraseType.number,"BX",7,0,new Complex(0,0),null),
                new ClsPhrase (enumPhraseType.number,"CX",7,0,new Complex(0,0),null),
                new ClsPhrase (enumPhraseType.number,"DX",7,0,new Complex(0,0),null),
                new ClsPhrase (enumPhraseType.number,"EX",7,0,new Complex(0,0),null),
                new ClsPhrase (enumPhraseType.number,"FX",7,0,new Complex(0,0),null),
                new ClsPhrase (enumPhraseType.number,"ANS",7,0,new Complex(0,0),null),
                //常量
                new ClsPhrase (enumPhraseType.number,"PI",7,0,new Complex(System.Math.PI,0),null),
                new ClsPhrase (enumPhraseType.number,"E",7,0,Complex.Exp(1),null)//因为这一个，所有的运算符或者常数不能以E开头。

            };

        public ArithmeticExpression()
        {
            arrClsPhrase = new ClsPhrase []{   //运算优先级1级
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"+",1,2,null,fun_plus),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"-",1,2,null,fun_minus),
                                               //运算优先级2级
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"*",2,2,null,fun_mutiple),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"/",2,2,null,fun_divide),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"%",2,2,null,fun_mod),
                                               //运算优先级3级
                                               //运算优先级4级
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"sinh",4,1,null,fun_sinh),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"cosh",4,1,null,fun_cosh),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"tanh",4,1,null,fun_tanh),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"sin",4,1,null,fun_sin),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"cos",4,1,null,fun_cos),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"tg",4,1,null,fun_tan),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"ctg",4,1,null,fun_ctg),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"asin",4,1,null,fun_asin),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"acos",4,1,null,fun_acos),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"atg",4,1,null,fun_atan),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"actg",4,1,null,fun_actg),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"arcsh",4,1,null,fun_arcsh),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"arcch",4,1,null,fun_arcch),
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"arcth",4,1,null,fun_arcth),

                                               new ClsPhrase (enumPhraseType.YunCuanFu,"abs",4,1,null,fun_abs),//绝对值
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"gamma",4,1,null,fun_Gamma),//伽玛函数
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"gammaln",4,1,null,fun_GammaLn),//
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"factorialln",4,1,null,fun_FactorialLn),//
                                               


                                               //运算优先级5级
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"ln",5,1,null,fun_ln),//以e为底的对数
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"lg",5,1,null,fun_lg),//以10为底的对数
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"log",5,2,null,fun_log),//以为底的对数
                                               //运算优先级6级
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"sqrt",6,1,null,fun_sqrt),//开平方
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"cbrt",6,1,null,fun_cbrt),//开立方
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"pow",6,2,null,fun_pow),//次幂
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"^",6,2,null,fun_pow),//次幂
                                               new ClsPhrase (enumPhraseType.YunCuanFu,"!",6,1,null,fun_Factorial)//阶乘
                                               //运算优先级7级
                                           };


        }

        public double Eval2(string expr)
        {
            try
            {
                string tmpexpr = expr.ToLower().Trim().Replace(" ", string.Empty);

                Stack post2 = ConvertExprBack(expr);

                Complex complex = Calc_ExprBack(post2);

                return complex.Real;

            }
            catch (Exception)
            {
                return 0;
                //throw;
            }


        }

        public string  Eval(string expr)
        {

            string tmpexpr = expr.ToLower().Trim().Replace(" ", string.Empty);

            Stack post2 = ConvertExprBack(expr);

            Complex complex = Calc_ExprBack(post2);

            SetVar("ANS", complex);//保存结果

            if (complex.Imaginary==0)
            {
                return complex.Real.ToString();//如果是实数运算，就只返回世俗就可以了。
            }

            string strReturn = "";//返回值

            if (complex.Real != 0)
            {
                strReturn += complex.Real.ToString();

            }


            if (complex.Imaginary != 0)
            {
                if (complex.Imaginary > 0)
                {
                    strReturn += "+" + complex.Imaginary.ToString() + "i";//大于零得加上一个“+”                    
                }
                else
                {
                    strReturn += complex.Imaginary.ToString() + "i";//小于0的情况下，一般已经有个负号了。 
                }
            }

            //如果实数虚数都为0，那么字符串应该为空
            if (strReturn == "")
            {
                strReturn = "0";//就为0
            }

            return strReturn;

        }


        private Random m_Random = null;



        /// <summary>
        /// 计算后缀表达式
        /// </summary>
        /// <param name="Stack1"></param>
        /// <returns></returns>
        public    Complex Calc_ExprBack(Stack Stack1)
        {
            
            /*
             * 1.    初始化一个空堆栈 
             * 2.    从左到右读入后缀表达式 
             * 3.    如果字符是一个操作数，把它压入堆栈。 
             * 4.    如果字符是个操作符，弹出两个操作数，执行恰当操作，然后把结果压入堆栈。如果您不能够弹出两个操作数，后缀表达式的语法就不正确。 
             * 5.    到后缀表达式末尾，从堆栈中弹出结果。若后缀表达式格式正确，那么堆栈应该为空。
            */

            Stack post = Stack1;//后缀表达式栈，这个顺序已经适合计算了
            Stack stackNumber = new Stack();//这个是操作数栈

            while (post.Count > 0)
            {

                ClsPhrase clsPhrase1 = (ClsPhrase)post.Pop();
                //判断词类型是否是操作数
                if (clsPhrase1.PhraseType == enumPhraseType.number)
                {
                    stackNumber.Push(clsPhrase1.Value);//操作数直接入操作数栈,是直接入操作数value就是复数类型的数据

                }
                else if (clsPhrase1.PhraseType == enumPhraseType.YunCuanFu)//如果是运算符
                {
                    switch (clsPhrase1.OperandType)//根据目数计算
                    {
                        case 1://一目运算
                            try
                            {
                                stackNumber.Push(clsPhrase1.calculate((Complex)stackNumber.Pop(), 0));
                            }
                            catch (System.Exception ex)
                            {
                                if (ex.Message == "堆栈为空。")
                                {
                                    throw new Exception(clsPhrase1.StrRegex + "找不到操作数");
                                }
                                else
                                {
                                    throw new Exception(ex.Message);
                                }
                            }
                            
                            break;
                        case 2://2目运算
                            try
                            {
                                stackNumber.Push(clsPhrase1.calculate((Complex)stackNumber.Pop(), (Complex)stackNumber.Pop()));
                            }
                            catch (System.Exception ex)
                            {
                                if (ex.Message == "堆栈为空。")
                                {
                                    throw new Exception(clsPhrase1.StrRegex + "找不到操作数");
                                }
                                else
                                {
                                    throw new Exception(ex.Message);
                                }

                            }
                            
                            break;
                        default:
                            break;
                    }

                }
            }

            //如果数据堆栈里有多个数据，就表明有错误
            if (stackNumber.Count>1)
            {
                throw new Exception(" 输入的算术表达式有误");
            }

            return ((Complex)stackNumber.Pop());

        }

        /// <summary>
        /// 判断这个函数是否有这些变量或者常量
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private bool checkVarAndConst(string str,int i)
        {
            //循环这些匹配
            for (int j = 0; j < arrClsPhrase2.Length; j++)
            {
                //首先查看这些匹配的长度，然后再截取字符串中相同长度的做比较，如果相等就认为是匹配的。
                int intLength = arrClsPhrase2[j].StrRegex.Length;
                try
                {
                    if (arrClsPhrase2[j].StrRegex.ToLower() == str.Substring(i, intLength))
                    {

                        return true;

                    }
                }
                catch (System.Exception ex)
                {

                }

            }

            return false;
        }
      
        /// <summary>
        /// 将中缀表达式转为后缀表达式,这个是我在原先作者的基础上修改的
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public    Stack ConvertExprBack(string expr)
        {
            /*
             * 新建一个Stack栈，用来存放运算符
             * 新建一个post栈，用来存放最后的后缀表达式
             * 从左到右扫描中缀表达式：
             * 1.若读到的是操作数，直接存入post栈，以#作为数字的结束
             * 2、若读到的是(,则直接存入stack栈
             * 3.若读到的是），则将stack栈中(前的所有运算符出栈，存入post栈
             * 4 若读到的是其它运算符，则将该运算符和stack栈顶运算符作比较：若高于或等于栈顶运算符， 则直接存入stack栈，
             * 否则将栈顶运算符（所有优先级高于读到的运算符的，不包括括号）出栈，存入post栈。最后将读到的运算符入栈
             * 当扫描完后，stack栈中还在运算符时，则将所有的运算符出栈，存入post栈
             * */
            expr = expr.ToLower();//转换成小写
            expr.Trim();//移除空白
            //expr = expr.Replace(" ", "");//转换空格为空
            expr += " ";//加上一个空格

            Stack post = new Stack();
            Stack stack = new Stack();

            int startIndex = 0;//这个仅仅是匹配数字的时候用
            DFAState dfaStart = DFAState.S0;//定义初态

            for (int i = 0; i <expr.Length ; i++)
            {
                char c = expr[i];
                //先判断这个字符是否是数字或者负号
                if ((char.IsDigit(c) || (c == '@'))
                    || ((c == '-') &&  (dfaStart != DFAState.S5)&&  (dfaStart != DFAState.S1) &&  (dfaStart != DFAState.S2) &&  (dfaStart != DFAState.S3) &&  (dfaStart != DFAState.S7))//等于负号，前一位不是数字和“)”，就认为这个是负号
                    ||((c=='-')&&(i==0)))//或者这个负号就是第一位字符 ,其他情况就认为这个是减法这个运算符了
                    //我想没必要做这个加法和正号的区别的，如果需要，就将上边的复制再修改就可以了。
                {


                    if ((dfaStart!=DFAState.S1)&&(dfaStart!=DFAState.S2))
                    {
                        dfaStart = DFAState.S1;//当一开始遇到一个数字，就是整数
                        startIndex = i;//定位数字最开始的位置
                    }

                }
                else if (c == '.')//当遇到小数点，就转换状态为浮点数态
                {
                    if (dfaStart == DFAState.S1)
                    {
                        dfaStart = DFAState.S2;
                    }
                    else if (dfaStart == DFAState.S2) //如果是浮点数态出现小数点就是错误
                    {
                        throw new Exception("浮点数"+expr.Substring(startIndex)+"出现2个小数点");

                    }

                }
                else if (c == 'i')//虚数
                {
                    //如果状态是整数或者浮点数或者科学计数法，并且后边一位字符不是字母或者数字，就认为这个是虚数,所有的数保存都是复数形式的
                    if (((dfaStart == DFAState.S1)
                        ||(dfaStart == DFAState.S2))
                        && (i < (expr.Length - 1))//防止最后一位不够，因为下边要判断最后一位
                        && (!char.IsDigit(expr[i+1]))
                        && (!char.IsLetter(expr[i+1])))
                    {
                        try
                        {
                            //到这部肯定就是得将这个虚数保存到堆栈中了
                            double dbl = Convert.ToDouble(expr.Substring(startIndex, i - startIndex).Replace('@', '-'));
                            Complex c1 = new Complex(0, dbl);
                            ClsPhrase p = new ClsPhrase(enumPhraseType.number, "", 0, 0, c1, null);
                            post.Push(p);
                        }
                        catch (System.Exception ex)
                        {
                            throw new Exception(expr.Substring(startIndex, i - startIndex+1)+"不能解释，" + ex.Message);	    
                        }

                        
                        //设置状态为虚数
                        dfaStart = DFAState.S3;
                    }

                }
                else if (c == '(')//左括号,左括号前应该不会有操作数
                {
                    //直接存入stack栈
                    dfaStart = DFAState.S0; 
                    ClsPhrase p = new ClsPhrase(enumPhraseType.leftbracket, "", 0, 0, null, null);
                    stack.Push(p);

                    //设置状态为左括号
                    dfaStart = DFAState.S6;

                }
                else if (c == ')')//右括号
                {
                    //如果状态是整数或者浮点数，这个是处理上一步的
                    if ((dfaStart == DFAState.S1)
                        || (dfaStart == DFAState.S2))
                    {
                        try
                        {                       
                            //就要保存这个操作数量，到这里应该是
                        double dbl = Convert.ToDouble(expr.Substring(startIndex, i - startIndex).Replace('@', '-'));
                        Complex c1 = new Complex(dbl,0);
                        ClsPhrase p = new ClsPhrase(enumPhraseType.number, "", 0, 0, c1, null);
                        post.Push(p);
                        }
                        catch (System.Exception ex)
                        {
                            throw new Exception(expr.Substring(startIndex, i - startIndex) + "不能解释，" + ex.Message);
                        }

                    }

                    //则将stack栈中 ( 前的所有运算符出栈，存入post栈
                    while (stack.Count > 0)
                    {
                        if (((ClsPhrase)stack.Peek()).PhraseType == enumPhraseType.leftbracket)
                        {
                            stack.Pop();
                            break;
                        }
                        else
                            post.Push(stack.Pop());
                    }

                    //设置状态为右括号
                    dfaStart = DFAState.S7;

                }
                else if (checkVarAndConst(expr,i))//这一步将判断是否是常数，比如PI，E等等,这些是直接存入post栈的
                {
                    dfaStart = DFAState.S5;//

                    //将这个常数直接存入堆栈中
                    //循环这些匹配
                    for (int j = 0; j < arrClsPhrase2.Length; j++)
                    {
                        //首先查看这些匹配的长度，然后再截取字符串中相同长度的做比较，如果相等就认为是匹配的。
                        int intLength = arrClsPhrase2[j].StrRegex.Length;
                        try
                        {
                            if (arrClsPhrase2[j].StrRegex.ToLower() == expr.Substring(i, intLength))
                            {
                                post.Push(arrClsPhrase2[j].DeepCopy());
                                //得加上这部分匹配的
                                i += intLength - 1;
                                break;
                            }
                        }
                        catch (System.Exception ex)
                        {
                            //这里主要会出现Substring超出边界的情况，不用理。
                        }

                    }

                }
                //到这里就是各种运算符了
                else{

                    bool isFind = false;//是否找到，如果没有找到，就认为没有符合的.
                    //如果状态是整数或者浮点数，这个是处理上一步的
                    if ((dfaStart == DFAState.S1)
                        || (dfaStart == DFAState.S2))
                    {
                        try
                        {
                            //就要保存这个操作数量，到这里应该是
                            double dbl = Convert.ToDouble(expr.Substring(startIndex, i - startIndex).Replace('@', '-'));
                            Complex c1 = new Complex(dbl, 0);
                            ClsPhrase p = new ClsPhrase(enumPhraseType.number, "", 0, 0, c1, null);
                            post.Push(p);
                            dfaStart = DFAState.S0;//设置状态为初态
                        }
                        catch (System.Exception ex)
                        {
                            throw new Exception(expr.Substring(startIndex, i - startIndex) + "不能解释，" + ex.Message);
                        }
                    }


                    //若读到的是其它运算符，则将该运算符和stack栈顶运算符作比较：若高于或等于栈顶运算符， 则直接存入stack栈，
                    //否则将栈顶运算符（所有优先级高于读到的运算符的，不包括括号）出栈，存入post栈。最后将读到的运算符入栈

                    //循环这些匹配
                    for (int j = 0; j < arrClsPhrase.Length; j++)
                    {
                        //首先查看这些匹配的长度，然后再截取字符串中相同长度的做比较，如果相等就认为是匹配的。
                        int intLength = arrClsPhrase[j].StrRegex.Length;
                        if (((i+intLength)<=expr.Length)
                            &&(arrClsPhrase[j].StrRegex.ToUpper()==expr.Substring(i,intLength).ToUpper()))
                        {

                                while ((stack.Count > 0)//当然是这个栈内得有东西
                                    &&(((ClsPhrase)stack.Peek()).PhraseType != enumPhraseType.leftbracket) //不等于括号
                                    && (arrClsPhrase[j].OperatorPriority <=((ClsPhrase)stack.Peek()).OperatorPriority) //优先级低于
                                    ) 
                                {
                                    post.Push(stack.Pop());
                                }

                                stack.Push(arrClsPhrase[j].DeepCopy());// 存入stack栈

                            //得加上这部分匹配的
                            i += intLength - 1;

                            dfaStart = DFAState.S4;//设置状态为运算

                            isFind = true;

                            break;//找到一个就返回
                            
                        }
                        
                    }

                    //如果没有找到并且不是空白，就认为这个是不能识别的。
                    if ((!isFind)&&(!char.IsWhiteSpace(c)))
                    {
                        string strError = "从" + (i + 1).ToString() + "位开始的\"" + expr.Substring(i) + "\"不能识别";
                        throw new Exception(strError);
                    }

                }

            }

            #region
            /**

            Stack post = new Stack();
            Stack stack = new Stack();
            string tmpstr;
            int pos;
            for (int i = 0; i <= expr.Length - 1; i++)
            {
                char c = expr[i];
                LetterType lt = JudgeLetterType(c, expr, i);

                if (lt == LetterType.Number)  //操作数
                {
                    GetCompleteNumber(expr, i, out tmpstr, out pos);
                    post.Push(tmpstr);
                    i = pos;// +1;
                }
                else if (lt == LetterType.OpeningParenthesis) //左括号(
                {
                    stack.Push(c);
                }
                else if (lt == LetterType.ClosingParenthesis) //右括号)
                {
                    while (stack.Count > 0)
                    {
                        if (stack.Peek().ToString() == "(")
                        {
                            stack.Pop();
                            break;
                        }
                        else
                            post.Push(stack.Pop());
                    }
                }
                else if (lt == LetterType.SimpleOperator)  //其它运算符
                {
                    if (stack.Count == 0)
                        stack.Push(c);
                    else
                    {

                        char tmpop = (char)stack.Peek();
                        if (tmpop == '(')
                        {
                            stack.Push(c);
                        }
                        else
                        {
                            if (GetPriority(c) >= GetPriority(tmpop))
                            {
                                stack.Push(c);
                            }
                            else
                            {
                                while (stack.Count > 0)
                                {
                                    object tmpobj = stack.Peek();
                                    if (GetPriority((char)tmpobj) > GetPriority(c))
                                    {
                                        if (tmpobj.ToString() != "(")
                                            post.Push(stack.Pop());
                                        else
                                            break;
                                    }
                                    else
                                        break;
                                }
                                stack.Push(c);
                            }
                        }


                    }
                }
                else if (lt == LetterType.Function)  //如果是一个函数，则完整取取出函数，当作一个操作数处理
                {
                    GetCompleteFunction(expr, i, out tmpstr, out pos);
                    post.Push(tmpstr);
                    i = pos;// +1;
                }

            }
             * 
             * */
            #endregion

            //当扫描完后，stack栈中还在运算符时，则将所有的运算符出栈，存入post栈
            while (stack.Count > 0)
            {
                post.Push(stack.Pop());
            }

            //再将堆栈颠倒，
            Stack stackReturn = new Stack();
            while (post.Count>0)
            {
                stackReturn.Push(post.Pop());
            }

            return stackReturn;
        }

        /// <summary>
        /// 取得变量值
        /// </summary>
        /// <param name="strVarName"></param>
        /// <returns></returns>
        public static Complex getVarAndConst(string strVarName)
        {
            //将这个常数直接存入堆栈中
            //循环这些匹配
            for (int j = 0; j < arrClsPhrase2.Length; j++)
            {
                //首先查看这些匹配的长度，然后再截取字符串中相同长度的做比较，如果相等就认为是匹配的。
                int intLength = arrClsPhrase2[j].StrRegex.Length;
                try
                {
                    if (arrClsPhrase2[j].StrRegex.ToLower() == strVarName.ToLower())
                    {
                        return (Complex)arrClsPhrase2[j].Value;
                    }
                }
                catch (System.Exception ex)
                {
                    //这里主要会出现Substring超出边界的情况，不用理。
                }

            }

            return Complex.Zero;
        }

        /// <summary>
        /// 更改变量值
        /// </summary>
        /// <param name="strVarName"></param>
        /// <param name="complex"></param>
        public static void SetVar(string strVarName, Complex complex)
        {
            //循环这些匹配
            for (int j = 0; j < arrClsPhrase2.Length; j++)
            {
                //首先查看这些匹配的长度，然后再截取字符串中相同长度的做比较，如果相等就认为是匹配的。
                int intLength = arrClsPhrase2[j].StrRegex.Length;
                try
                {
                    if (arrClsPhrase2[j].StrRegex.ToLower() == strVarName.ToLower())
                    {

                        arrClsPhrase2[j].Value = complex;//赋值

                    }
                }
                catch (System.Exception ex)
                {

                }

            }
        }

        /// <summary>
        /// 阶乘
        /// </summary>
        /// <param name="i">阶数</param>
        /// <returns></returns>
        private double Factorial(double i)
        {
            return ((i <= 1) ? 1 : (i * Factorial(i - 1)));
        }

        //如下是支持的各种运算,我都以fun开头，表示这些都是函数
        private   Complex fun_plus(Complex c1, Complex c2)
        {
            return c1 + c2;
        }
        private  Complex fun_minus(Complex c1, Complex c2)
        {
            return c2 - c1;
        }
        private  Complex fun_mutiple(Complex c1, Complex c2)
        {
            return c1 * c2;
        }
        private  Complex fun_divide(Complex c1, Complex c2)
        {
            return c2 / c1;
        }
        private  Complex fun_mod(Complex c1, Complex c2)
        {
            //只能是实数求余数
            return new Complex(c2.Real % c1.Real, 0);
        }
        private Complex fun_abs(Complex c1, Complex c2)
        {
            //只能是实数
            return Complex.Abs(c1);
        }
        private Complex fun_sqrt(Complex c1, Complex c2)
        {
            if (c1.Imaginary==0)
            {
                return new Complex(System.Math.Sqrt(c1.Real), 0);
            }
            return Complex.Sqrt(c1);//开平方
            
        }
        private Complex fun_cbrt(Complex c1, Complex c2)
        {
            if (c1.Imaginary == 0)
            {
                return new Complex(System.Math.Pow(c1.Real,1.0/3.0), 0);
            }
            return Complex.Pow(c1, 1.0/3.0);//开立方
        }

        private Complex fun_pow(Complex c1, Complex c2)
        {
            if ((c1.Imaginary == 0)&&(c2.Imaginary==0))
            {
                return new Complex(System.Math.Pow(c2.Real, c1.Real), 0);
            }
            return Complex.Pow(c2, c1);//开立方
        }

        private Complex fun_Factorial(Complex c1, Complex c2)
        {
            return new Complex(Factorial(c1.Real), 0);
        }

        private Complex fun_Gamma(Complex c1, Complex c2)
        {
            return new Complex(0, 0);
            //return new Complex(MathNet.Numerics.SpecialFunctions.Gamma(c1.Real), 0);
        }
        private Complex fun_GammaLn(Complex c1, Complex c2)
        {
            return new Complex(0, 0);
            //return new Complex(MathNet.Numerics.SpecialFunctions.GammaLn(c1.Real), 0);
        }
        private Complex fun_FactorialLn(Complex c1, Complex c2)
        {
            return new Complex(0, 0);
            //return new Complex(MathNet.Numerics.SpecialFunctions.FactorialLn((int)c1.Real), 0);
        }


        //log系列
        private Complex fun_ln(Complex c1, Complex c2)
        {
            if (c1.Imaginary==0)
            {
                return new Complex(System.Math.Log(c1.Real), 0);
            }
            return Complex.Log(c1);
        }
        private Complex fun_lg(Complex c1, Complex c2)
        {
            if (c1.Imaginary==0)
            {
                return new Complex(System.Math.Log10(c1.Real), 0);
            }
            return Complex.Log10(c1);
        }
        private Complex fun_log(Complex c1, Complex c2)
        {
            if( (c2.Imaginary==0)&&(c1.Imaginary == 0))
            {
                return new Complex(System.Math.Log(c1.Real,c2.Real),0);
            }
            return Complex.Log(c1, c2.Real);//
        }

        //三角函数系列
        private Complex fun_sin(Complex c1, Complex c2)
        {
            if (JiaoDuDanWei == enumJiaoDuDanWei.HuDu)
            {
                if (c1.Imaginary==0)
                {
                    return new Complex(System.Math.Sin(c1.Real), 0);
                }

                return Complex.Sin(c1);
            }
            else if (JiaoDuDanWei == enumJiaoDuDanWei.JiaoDu)
            {
                if (c1.Imaginary==0)
                {
                    return new Complex(System.Math.Sin(c1.Real * System.Math.PI / 180), 0);
                }
                return Complex.Sin(c1 * System.Math.PI / 180);
            }
            return new Complex(0, 0);

        }
        private Complex fun_cos(Complex c1, Complex c2)
        {
            if (JiaoDuDanWei == enumJiaoDuDanWei.HuDu)
            {
                return Complex.Cos(c1);
            }
            else if (JiaoDuDanWei == enumJiaoDuDanWei.JiaoDu)
            {
                return Complex.Cos(c1 * System.Math.PI / 180);
            }
            return new Complex(0, 0);

        }
        private Complex fun_tan(Complex c1, Complex c2)
        {
            if (JiaoDuDanWei == enumJiaoDuDanWei.HuDu)
            {
                return Complex.Tan(c1);
            }
            else if (JiaoDuDanWei == enumJiaoDuDanWei.JiaoDu)
            {
                return Complex.Tan(c1 * System.Math.PI / 180);
            }
            return new Complex(0, 0);

        }
        private Complex fun_ctg(Complex c1, Complex c2)
        {
            if (JiaoDuDanWei == enumJiaoDuDanWei.HuDu)
            {
                return 1.0/Complex.Tan(c1);
            }
            else if (JiaoDuDanWei == enumJiaoDuDanWei.JiaoDu)
            {
                return 1.0/Complex.Tan(c1 * System.Math.PI / 180);
            }
            return new Complex(0, 0);

        }
        //反三角函数
        private Complex fun_asin(Complex c1, Complex c2)
        {
            if (JiaoDuDanWei == enumJiaoDuDanWei.HuDu)
            {

                return Complex.Asin(c1);
            }
            else if (JiaoDuDanWei == enumJiaoDuDanWei.JiaoDu)
            {
                if (c1.Imaginary==0)
                {
                    return new Complex(System.Math.Asin(c1.Real) / System.Math.PI * 180, 0);
                }
                return Complex.Asin(c1) / System.Math.PI * 180;
            }
            return new Complex(0, 0);

        }
        private Complex fun_acos(Complex c1, Complex c2)
        {
            if (JiaoDuDanWei == enumJiaoDuDanWei.HuDu)
            {
                return Complex.Acos(c1);
            }
            else if (JiaoDuDanWei == enumJiaoDuDanWei.JiaoDu)
            {
                return Complex.Acos(c1) / System.Math.PI * 180;
            }
            return new Complex(0, 0);

        }
        private Complex fun_atan(Complex c1, Complex c2)
        {
            if (JiaoDuDanWei == enumJiaoDuDanWei.HuDu)
            {
                return Complex.Atan(c1);
            }
            else if (JiaoDuDanWei == enumJiaoDuDanWei.JiaoDu)
            {
                return Complex.Atan(c1) / System.Math.PI * 180;
            }
            return new Complex(0, 0);

        }
        private Complex fun_actg(Complex c1, Complex c2)
        {
            if (JiaoDuDanWei == enumJiaoDuDanWei.HuDu)
            {
                return System.Math.PI/2-Complex.Atan(c1);
            }
            else if (JiaoDuDanWei == enumJiaoDuDanWei.JiaoDu)
            {
                return (System.Math.PI / 2 - Complex.Atan(c1)) / System.Math.PI * 180;
            }
            return new Complex(0, 0);

        }

        //双曲函数系列
        private Complex fun_sinh(Complex c1, Complex c2)
        {
            return Complex.Sinh(c1);
        }
        private Complex fun_cosh(Complex c1, Complex c2)
        {
            return Complex.Cosh(c1);
        }
        private Complex fun_tanh(Complex c1, Complex c2)
        {
            return Complex.Tanh(c1);
        }

        //反双曲函数系列
        /**
         * arcsh(x) = ln[x + sqrt(x^2 + 1）]
         * arcch(x) = ln[x + sqrt(x^2 - 1）]
         * arcth(x) = ln[sqrt（1 - x^2） / （1 - x)] = ln[（1 + x) / （1 - x)] / 2
         * */
        private Complex fun_arcsh(Complex c1, Complex c2)
        {
            return Complex.Log(c1 + Complex.Sqrt(c1 * c1 + 1));
        }
        private Complex fun_arcch(Complex c1, Complex c2)
        {
            return Complex.Log(c1 + Complex.Sqrt(c1 * c1 -1));
        }
        private Complex fun_arcth(Complex c1, Complex c2)
        {
            return Complex.Log((1+c1)/(1-c1))/2;
        }
    }

    /// <summary>
    /// 可以检测到的表达式错误的Exception
    /// </summary>
    public class ExpressionException : Exception
    {
        public override string Message
        {
            get
            {
                return base.Message;
            }
        }
    }

    /// <summary>
    /// 字符类别,这个都没用过，我在词类型中兼容了这个了。
    /// </summary>
    public enum LetterType
    {
        Number,//数字，我打算用复数的形式表示
        SimpleOperator,//简单运算符
        Function,//函数
        OpeningParenthesis,//左括号
        ClosingParenthesis//右括号
    }




}
